// 没有上司的舞会
// 某大学有n个职员，编号为1...n
// 他们之间有从属关系，也就是说他们的关系就像一棵以校长为根的树
// 父结点就是子结点的直接上司
// 现在有个周年庆宴会，宴会每邀请来一个职员都会增加一定的快乐指数 
// 但是如果某个职员的直接上司来参加舞会了
// 那么这个职员就无论如何也不肯来参加舞会了
// 所以请你编程计算邀请哪些职员可以使快乐指数最大
// 返回最大的快乐指数。
// 测试链接 : https://www.luogu.com.cn/problem/P1352
// 本题和讲解037的题目7类似
// 测试链接 : https://leetcode.cn/problems/house-robber-iii/
// 提交以下的code，可以直接通过

#include <bits/stdc++.h>

using namespace std;

const int MAXN = 6001;
int nums[MAXN];
bool boss[MAXN];
// 链式链式前向星
int head[MAXN];
int next[MAXN];
int to[MAXN];
int cnt = 1;
// 动态规划表
// no[i] : i为头的整棵树，在i不来的情况下，整棵树能得到的最大快乐值
int no[MAXN];
// no[i] : i为头的整棵树，在i来的情况下，整棵树能得到的最大快乐值
int yes[MAXN];

// 链式前向星加边
void addEdge(int u, int v)
{
    to[cnt] = v;
    ::next[cnt] = head[u];
    head[u] = cnt++;
}

// 初始化
void build(int n)
{
    fill(boss + 1, boss + n + 1, true);
    fill(head + 1, head + n + 1, 0);
    cnt = 1;
}

// 快读
inline int read()
{
    char ch = getchar();
    int x = 0, f = 1;
    while(ch < '0' || ch > '9')
    {
        if(ch == '-') f = -1;
        ch = getchar();
    }
    while(ch >= '0' && ch <= '9')
    {
        x = 10 * x + ch - '0';
        ch = getchar();
    }
    return f * x;
}

// 以 u 为根的最大快乐值
void f(int u)
{
    no[u] = 0;
    yes[u] = nums[u];
    // 链式前向星遍历
    for(int ei = head[u]; ei; ei = ::next[ei])
    {
        int v = to[ei];
        f(v);
        no[u] += max(no[v], yes[v]);
        yes[u] += no[v];
    }
}

int main()
{
    int n = read();
    for(int i = 1; i <= n; ++i) nums[i] = read();
    build(n);
    for(int i = 1, low, high; i < n; ++i)
    {
        low = read(), high = read();
        // 有向边
        addEdge(high, low);
        boss[low] = false;
    }

    // 找出根
    int root;
    for(int i = 1; i <= n; ++i)
    {
        if(boss[i])
        {
            root = i;
            break;
        }
    }
    f(root);
    printf("%d\n", max(no[root], yes[root]));

    return 0;
}